# -*- coding: utf-8 -*-
# Filename: logging_config.py

import os
import logging

"""
    import LogConfig
    logger = LogConfig.getLogger()
    or
    import logging
    import logging.config
    import LogConfig
    # 导入配置文件
    logging.config.dictConfig(LogConfig.color_logging_by_size())
    logger = logging.getLogger('main')
"""


class ColorFormatter(logging.Formatter):
    """
    在TTY中使用:
        Format添加 %(color)s XXX %(color_stop)s两个标签
                    XXX则会着色打印
        例如:
            "%(color)s %(message)s%(color_stop)s"
    """
    # TODO(jd) Allow configuration
    LEVEL_COLORS = {
        logging.DEBUG: '\033[00;32m',  # GREEN
        logging.INFO: '\033[00;36m',  # CYAN
        logging.WARN: '\033[01;33m',  # BOLD YELLOW
        logging.ERROR: '\033[01;31m',  # BOLD RED
        logging.CRITICAL: '\033[01;31m',  # BOLD RED
    }

    COLOR_STOP = '\033[0m'

    def format(self, record):
        if getattr(record, "_stream_is_a_tty", False):
            record.color = self.LEVEL_COLORS[record.levelno]
            record.color_stop = self.COLOR_STOP
        else:
            record.color = ""
            record.color_stop = ""
        s = super(ColorFormatter, self).format(record)
        del record.color
        del record.color_stop
        return s


class TTYDetectorStreamHandler(logging.StreamHandler):
    """Stream handler that adds a hint in the record if the stream is a TTY."""

    def format(self, record):
        if hasattr(self.stream, "isatty"):
            record._stream_is_a_tty = self.stream.isatty()
        else:
            record._stream_is_a_tty = False
        s = super(TTYDetectorStreamHandler, self).format(record)
        del record._stream_is_a_tty
        return s


# base logging 配置
def logging_by_size(log_dir=None, log_prefix='log'):
    if log_dir is not None:
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        log_prefix = os.path.join(log_dir, log_prefix)
    rotating_size = 1024 * 1024 * 100     # 100 MB
    return {
        "version": 1,
        "disable_existing_loggers": True,
        "incremental": False,
        "formatters": {
            "ConsoleFormatter": {
                "format": "%(asctime)s %(name)s %(levelname)s: %(message)s",
                "datefmt": "%Y-%m-%d %H:%M:%S"
            },
            "FileFormatter": {
                "format": "%(asctime)s %(levelname)-8s %(message)s [%(module)-10s line:%(lineno)3d]"
            }
        },
        "filters": {
            "LevelFilter": {
                "level": ["INFO", "WARNING", "ERROR", "CRITICAL"]
            }
        },
        "handlers": {
            "ConsoleHandler": {
                "class": "logging.StreamHandler",
                "formatter": "ConsoleFormatter",
                "filters": ["LevelFilter"]
            },
            "RotatingHandler": {
                "class": "logging.handlers.RotatingFileHandler",
                "formatter": "FileFormatter",
                "filters": ["LevelFilter"],
                "filename": log_prefix+"_info.log",
                "maxBytes": rotating_size,
                "backupCount": 50,
                "encoding": "utf8"
            },
            "RotatingErrorHandler": {
                "class": "logging.handlers.RotatingFileHandler",
                "formatter": "FileFormatter",
                "filters": ["LevelFilter"],
                "filename": log_prefix+"_error.log",
                "level": "ERROR",
                "maxBytes": rotating_size,
                "backupCount": 50,
                "encoding": "utf8"
            },
            "NullHandler": {
                "class": "logging.NullHandler"
            }
        },
        "loggers": {
            "main": {
                "handlers": ["ConsoleHandler", "RotatingHandler", "RotatingErrorHandler"],
                "qualname": "main",
                "propagate": 0,
                "enabled": True
            }
        },
        "root": {
            "handlers": ["ConsoleHandler", "RotatingHandler", "RotatingErrorHandler"],
            "level": "INFO"
        }
    }


def color_logging_by_size(log_dir=None, log_prefix='log'):
    conf = logging_by_size(log_dir, log_prefix)
    formatter = {
        "()": "%s.ColorFormatter" % __name__,
        "format": "%(asctime)s %(color)s%(levelname)-8s %(message)s%(color_stop)s [%(module)-10s line:%(lineno)3d]",
        "datefmt": "%Y-%m-%d %H:%M:%S"
    }
    handler = {
        "class": "%s.TTYDetectorStreamHandler" % __name__,
        "formatter": "ColorConsoleFormatter",
        "filters": ["LevelFilter"]
    }
    conf["formatters"]["ColorConsoleFormatter"] = formatter
    conf["handlers"]["ConsoleHandler"] = handler
    return conf


def logging_by_time(log_dir=None, log_prefix='log'):
    conf = logging_by_size(log_dir, log_prefix)
    if log_dir is not None:
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        log_prefix = os.path.join(log_dir, log_prefix)
    handler = {
        "class": "logging.handlers.TimedRotatingFileHandler",
        "formatter": "FileFormatter",
        "filters": ["LevelFilter"],
        "filename": log_prefix+"_info.log",
        "when": "W0",
        "interval": 1,
        "backupCount": 50,
        "encoding": "utf8"
    }
    errorhandler = {
        "class": "logging.handlers.TimedRotatingFileHandler",
        "formatter": "FileFormatter",
        "filters": ["LevelFilter"],
        "filename": log_prefix+"_error.log",
        "level": "ERROR",
        "when": "W0",
        "interval": 1,
        "backupCount": 50,
        "encoding": "utf8"
    }
    conf["handlers"]["RotatingHandler"] = handler
    conf["handlers"]["RotatingErrorHandler"] = errorhandler
    return conf


default = logging_by_size
logger_dict = logging.Logger.manager.loggerDict


def get_logger():
    if 'main' in logger_dict:
        return logger_dict['main']
    import logging.config
    conf = color_logging_by_size("logs")
    logging.config.dictConfig(conf)
    return logging.getLogger('main')
